package com.qkl.xiatang.app.service.impl;

import com.qkl.xiatang.app.dto.pond.PondNamesVO;
import com.qkl.xiatang.app.dto.pond.QueryPondNamesInDTO;
import com.qkl.xiatang.app.dto.pond.QueryPondNamesOutDTO;
import com.qkl.xiatang.app.entity.feed.AllocBaseEntity;
import com.qkl.xiatang.app.entity.feed.FeedAllocDetailEntity;
import com.qkl.xiatang.app.entity.pond.PondEntity;
import com.qkl.xiatang.app.mapper.PondManagerMapper;
import com.qkl.xiatang.app.utils.AppUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Slf4j
@Service
public class PondNamesService {

    @Autowired
    private PondManagerMapper pondManagerMapper;

    /**
     * 查询塘口名称
     * @param pondIdList
     * @return
     */
    public List<String> queryPondNames(List<String> pondIdList){
        return pondManagerMapper.queryPondNames(pondIdList);
    }

    public List<String> queryPondNames(String pondId){
        List<String> pondIdList = new ArrayList<>();
        pondIdList.add(pondId);
        return this.queryPondNames(pondIdList);
    }

    /**
     * 查询喂料任务塘口名称
     * @param companyId
     * @param allocDate
     * @param serialNo
     * @param userIdFieldName
     * @param userNameFieldName
     * @return
     */
    public List<QueryPondNamesOutDTO>  queryFeedPondNames(String companyId, Date allocDate, Integer serialNo, String userIdFieldName, String userNameFieldName,String feedId){
        QueryPondNamesInDTO param = new QueryPondNamesInDTO();
        param.setCompanyId(companyId);
        param.setAllocDate(allocDate);
        param.setSerialNo(serialNo);
        param.setUserIdFieldName(userIdFieldName);
        param.setUserNameFieldName(userNameFieldName);
        param.setFeedId(feedId);
        return groupPondNames(pondManagerMapper.queryFeedPondNames(param));
    }

    /**
     * 查询称料任务塘口名称
     * @param task
     * @return
     */
    public List<QueryPondNamesOutDTO>  queryWeighPondNames(AllocBaseEntity task){
        List<QueryPondNamesOutDTO> list = null;
        if(task instanceof FeedAllocDetailEntity){
            FeedAllocDetailEntity feedTask = (FeedAllocDetailEntity)task;
            list = this.queryFeedWeighPondNames(task.getCompanyId(), task.getAllocDate(), feedTask.getSerialNo(),task.getFeedId());
        }else {
            list = this.queryZooWeighPondNames(task.getCompanyId(), task.getAllocDate(), task.getFeedId());
        }
        return list;
    }

    /**
     * 查询喂料称料任务塘口名称
     * @param companyId
     * @param allocDate
     * @param serialNo
     * @return
     */
    public List<QueryPondNamesOutDTO>  queryFeedWeighPondNames(String companyId, Date allocDate, Integer serialNo,String feedId){
        return this.queryFeedPondNames(companyId,allocDate,serialNo,"weigh_user_id","weigh_user_name",feedId);
    }

    /**
     * 查询饲料、动保喂料任务塘口名称
     * @param task
     * @return
     */
    public List<QueryPondNamesOutDTO>  queryFeedPondNames(AllocBaseEntity task){
        if(task instanceof FeedAllocDetailEntity){
            FeedAllocDetailEntity feedTask = (FeedAllocDetailEntity)task;
            return this.queryFeedFeedPondNames(task.getCompanyId(), task.getAllocDate(), feedTask.getSerialNo(),task.getFeedId());
        }
        return this.queryZooFeedPondNames(task.getCompanyId(),task.getAllocDate(),task.getFeedId());
    }

    /**
     * 查询喂料喂料任务塘口名称
     * @param companyId
     * @param allocDate
     * @param serialNo
     * @return
     */
    public List<QueryPondNamesOutDTO>  queryFeedFeedPondNames(String companyId, Date allocDate, Integer serialNo,String feedId){
        return this.queryFeedPondNames(companyId,allocDate,serialNo,"feed_user_id","feed_user_name",feedId);
    }

    /**
     * 查询查料台任务塘口名称
     * @param companyId
     * @param allocDate
     * @param serialNo
     * @return
     */
    public List<QueryPondNamesOutDTO>  queryCheckPondNames(String companyId, Date allocDate, Integer serialNo){
        return this.queryFeedPondNames(companyId,allocDate,serialNo,"check_user_id","check_user_name","");
    }

    /**
     * 查询动保任务塘口名称
     * @param companyId
     * @param allocDate
     * @param userIdFieldName
     * @param userNameFieldName
     * @return
     */
    public List<QueryPondNamesOutDTO>  queryZooPondNames(String companyId, Date allocDate,  String userIdFieldName, String userNameFieldName,String feedId){
        QueryPondNamesInDTO param = new QueryPondNamesInDTO();
        param.setCompanyId(companyId);
        param.setAllocDate(allocDate);
        param.setUserIdFieldName(userIdFieldName);
        param.setUserNameFieldName(userNameFieldName);
        param.setFeedId(feedId);
        return groupPondNames(pondManagerMapper.queryZooPondNames(param));
    }

    /**
     * 查询动保称料任务塘口名称
     * @param companyId
     * @param allocDate
     * @return
     */
    public List<QueryPondNamesOutDTO>  queryZooWeighPondNames(String companyId, Date allocDate,String feedId){
        return this.queryZooPondNames(companyId,allocDate,"weigh_user_id","weigh_user_name",feedId);
    }

    /**
     * 查询动保喂料任务塘口名称
     * @param companyId
     * @param allocDate
     * @return
     */
    public List<QueryPondNamesOutDTO>  queryZooFeedPondNames(String companyId, Date allocDate,String feedId){
      return this.queryZooPondNames(companyId,allocDate,"feed_user_id","feed_user_name",feedId);
    }


    /**
     * 未喂料塘口名
     * @param companyId
     * @param allocDate
     * @param serialNo
     * @param tableName
     * @return
     */
    private List<QueryPondNamesOutDTO>  queryUnfeededPondNames(String companyId, Date allocDate, Integer serialNo, String tableName){
        QueryPondNamesInDTO param = new QueryPondNamesInDTO();
        param.setCompanyId(companyId);
        param.setAllocDate(allocDate);
        param.setSerialNo(serialNo);
        param.setTableName(tableName);
        List<QueryPondNamesOutDTO> list = groupFeedIdList(pondManagerMapper.queryUnfeededPondNames(param));
        if(ObjectUtils.isEmpty(list)){
            return new ArrayList<>();
        }
        for (QueryPondNamesOutDTO dto : list){
            dto.setPondNames(pondManagerMapper.queryPondNameList(dto.getPondIdSet()));
        }
        return list;
    }

    private static List<QueryPondNamesOutDTO> groupFeedIdList(List<QueryPondNamesOutDTO>  list){
        if(ObjectUtils.isEmpty(list)){
            return new ArrayList<>();
        }
        Map<String,QueryPondNamesOutDTO> map = new HashMap<>();
        for(QueryPondNamesOutDTO dto : list){
            dto.parseFeedIdList();

            Set<String> set = new TreeSet<>();
            set.addAll(dto.getFeedIdSet());
            String key = String.join("",set);
            if(!map.containsKey(key)){
                dto.setPondIdSet(new HashSet<>());
                map.put(key,dto);
            }
            map.get(key).getPondIdSet().add(dto.getPondId());
        }
        List<QueryPondNamesOutDTO> returnList = new ArrayList<>();
        returnList.addAll(map.values());
        return returnList;
    }

    /**
     * 饲料未喂料塘口名
     * @param companyId
     * @param allocDate
     * @param serialNo
     * @return
     */
    public List<QueryPondNamesOutDTO>  queryUnfeededFeedPondNames(String companyId, Date allocDate, Integer serialNo){
        return this.queryUnfeededPondNames(companyId,allocDate,serialNo,"feed_alloc_detail");
    }

    /**
     * 动保未喂料塘口名
     * @param companyId
     * @param allocDate
     * @return
     */
    public List<QueryPondNamesOutDTO>  queryUnfeededZooPondNames(String companyId, Date allocDate){
        return this.queryUnfeededPondNames(companyId,allocDate,null,"zoo_alloc_detail");
    }

    /**
     * 未查料台塘口名
     * @param companyId
     * @param allocDate
     * @param serialNo
     * @return
     */
    public List<QueryPondNamesOutDTO>  queryUncheckedPondNames(String companyId, Date allocDate, Integer serialNo){
        QueryPondNamesInDTO param = new QueryPondNamesInDTO();
        param.setCompanyId(companyId);
        param.setAllocDate(allocDate);
        param.setSerialNo(serialNo);
        return groupPondNames(pondManagerMapper.queryUncheckedPondNames(param));
    }

    /**
     * 未配料塘口名列表
     * @param companyId
     * @param templateId
     * @param allocDate
     * @param serialNo
     * @return
     */
    public PondNamesVO queryNotAllocPondNames(String companyId,String templateId,Date allocDate,Integer serialNo){
        QueryPondNamesInDTO param = new QueryPondNamesInDTO();
        param.setCompanyId(companyId);
        param.setAllocDate(allocDate);
        param.setSerialNo(serialNo);
        param.setTemplateId(templateId);

        PondNamesVO vo = new PondNamesVO();
        vo.setPondList(pondManagerMapper.queryNotAllocPondNames(param));
        vo.fetchPondIdAndName();
        return vo;
    }


    private static List<QueryPondNamesOutDTO> groupPondNames(List<QueryPondNamesOutDTO> list ){
        if(ObjectUtils.isEmpty(list)){
            return new ArrayList<>();
        }
        Map<String,QueryPondNamesOutDTO> map = new HashMap<>();
        for(QueryPondNamesOutDTO dto : list){
            List<PondEntity> pondList = dto.getPondList();
            if(ObjectUtils.isNotEmpty(pondList)){
                dto.setPondNames(new ArrayList<>());
                dto.setPondIdSet(new TreeSet<>());
                for(PondEntity pondEntity : pondList){
                    dto.getPondNames().add(pondEntity.getName());
                    dto.getPondIdSet().add(pondEntity.getId());
                }
            }

            String key = StringUtils.trimToEmpty(dto.getUserId()) + String.join("",dto.getPondNames());
            if(!map.containsKey(key)){
                dto.setFeedIdSet(new HashSet<>());
                map.put(key,dto);
            }
            map.get(key).getFeedIdSet().addAll(AppUtils.stringToList(dto.getFeedId()));
        }
        List<QueryPondNamesOutDTO> returnList = new ArrayList<>();
        returnList.addAll(map.values());
        return returnList;
    }


}
